// ==UserScript==
// @name         YuKeTang-PPTHelper
// @namespace    https://bbs.tampermonkey.net.cn/
// @version      0.1.0
// @description  download ppt from yuketang
// @author       MrSuM
// @match        *://www.yuketang.cn/*
// ==/UserScript==

(function () {
    'use strict';
    console.log("YuKeTang-PPTHelper v0.1.0");

    // Defines APIs for interacting with YuKeTang
    const YuKeTangAPIs = {
        /**
         * Fetches presentation data
         * @param {string} presentation_id - The ID of the presentation
         * @param {string} lesson_id - The ID of the lesson
         * @returns {Promise} A promise that resolves with the presentation data
         */
        get_presentation_data(presentation_id, lesson_id) {
            return fetch(`https://www.yuketang.cn/api/v3/lesson-summary/student/presentation?presentation_id=${presentation_id}&lesson_id=${lesson_id}`)
                .then(res => res.json())
                .then(res => {
                    if (res.code !== 0) {
                        // reject(`ERROR get_lesson_summary msg:${res.msg}`);
                        return null;
                    }
                    return res.data;
                });
        },
        /**
         * Fetches lesson summary data
         * @param {string} lesson_id - The ID of the lesson
         * @returns {Promise} A promise that resolves with the lesson summary data
         */
        get_lesson_summary(lesson_id) {
            return fetch(`https://www.yuketang.cn/api/v3/lesson-summary/student?lesson_id=${lesson_id}`)
                .then(res => res.json())
                .then(res => {
                    if (res.code !== 0) {
                        // reject(`ERROR get_lesson_summary msg:${res.msg}`);
                        return null;
                    }
                    return res.data;
                })
        },
        /**
         * Fetches card detlist data
         * @param {string} courseware_id - The ID of the courseware
         * @returns {Promise} A promise that resolves with the card detlist data
         */
        get_card_detlist(courseware_id) {
            return fetch(`https://www.yuketang.cn/v2/api/web/cards/detlist/${courseware_id}?classroom_id=1`)
                .then(res => res.json())
                .then(res => {
                    if (res.errcode !== 0) {
                        // reject(`ERROR get_lesson_summary msg:${res.msg}`);
                        console.log(`ERROR get_card_detlist code:${res.errcode} msg:${res.errmsg}`);
                        return null;
                    }
                    return res.data;
                })
        }
    }

    /**
     * Retrieves student card data from local storage
     * @returns {Object} The student card data
     */
    const get_studentCards_data = function () {
        let data = localStorage.getItem('vuex');
        data = JSON.parse(data);
        return data.logData;
    }

    /**
     * Opens a new window with a given URL and returns a promise
     * @param {string} url - The URL to open
     * @returns {Promise} A promise that resolves when the window loads
     */
    const openWindowWithPromise = function (url) {
        return new Promise((resolve, reject) => {
            const newWindow = window.open(url, '_blank');

            if (!newWindow) {
                reject(new Error('Failed to open new window'));
            } else {
                newWindow.addEventListener('load', () => {
                    resolve(newWindow);
                }, false);

                newWindow.addEventListener('error', () => {
                    reject(new Error('Window load error'));
                }, false);
            }
        });
    }

    /**
     * Downloads a file by creating a temporary <a> element and simulating a click event.
     * This method works around cross-domain security restrictions without requiring server-side handling.
     *
     * @param {string} url - The URL of the file to download
     * @param {string} filename - The name of the file, including its extension
     */
    const downloadFile = function (url, filename, buttom) {
        console.log("Download", url, filename)

        const origin_text = buttom.innerHTML;
        const xhr = new XMLHttpRequest();
        xhr.open("GET", url, true);
        xhr.responseType = "blob"; // 设置响应类型为blob
        xhr.onprogress = function (e) {
            console.log("progress", e.loaded, e.total);
            buttom.innerHTML = `${origin_text} ${((e.loaded / e.total) * 100).toFixed(0)}%`;
        };
        xhr.onload = function () {
            if (this.status === 200) {
                const blob = this.response;
                const urlObject = URL.createObjectURL(blob);
                const a = document.createElement("a");
                a.href = urlObject;
                a.download = filename || "video.mp4"; // 如果没有指定文件名，默认为video.mp4
                a.style.display = "none";
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(urlObject);
            }
            setTimeout(() => {
                buttom.innerHTML = origin_text;
            }, 3000);
        };
        xhr.send();
    }

    /**
     * Handles printing based on the type of content
     * @param {number} type - The type of content to print
     * @param {string} presentation_id - The ID of the presentation
     * @param {string} lesson_id - The ID of the lesson
     */
    const go_print = async function (type, presentation_id, lesson_id) {
        console.log("Print", type, presentation_id, lesson_id)

        switch (type) {
            case 2:
                await openWindowWithPromise("https://www.yuketang.cn/web/print");
                break;

            case 14:
                let data = await YuKeTangAPIs.get_presentation_data(presentation_id, lesson_id);
                let p = {
                    "Slides": data.slides,
                    "Width": data.presentation.width,
                    "Height": data.presentation.height,
                    "Title": data.presentation.title,
                    "printType": 14
                };
                localStorage.setItem("rain_print", JSON.stringify(p));

                // window.open("https://www.yuketang.cn/web/print");
                await openWindowWithPromise("https://www.yuketang.cn/web/print");
                break;

            default:
                console.log("Unsupport type", type);
                break;
        }
    }

    /**
     * Updates the student card UI with print buttons
     * @param {HTMLElement} node - The student card element
     */
    const student_card_update = async function (node) {
        // Data
        // let title = node.querySelector("h2").innerText;
        let title = node.querySelector("h2").innerHTML;
        let card_data = get_studentCards_data().filter(item => title.indexOf(item.title) !== -1)[0];

        if (!card_data) {
            return;
        }

        // UI
        // let mount = node.querySelector(".sub-info");
        let mount = node.querySelector(".activity-box");
        let root = document.createElement("div");
        root.style.display = "flex";
        root.style.flexDirection = "column";
        root.style.alignItems = "center";
        root.style.justifyContent = "center";

        // Info
        let info = document.createElement("p");
        info.innerHTML = `title:${card_data.title} - courseware_id:${card_data.courseware_id} - type:${card_data.type}`;
        root.appendChild(info);

        //  课程
        if (card_data.type == 2) {
            let presentation_data = await YuKeTangAPIs.get_card_detlist(card_data.courseware_id, card_data.courseware_id);

            const files_list = [];
            presentation_data.Slides.forEach(slide => {
                slide.Shapes.forEach(shape => {
                    if (shape.file_title) {
                        files_list.push({
                            name: shape.file_title,
                            url: shape.playurl
                        })
                    }
                });
            });
            files_list.forEach(file => {
                let btn = document.createElement("button");
                btn.style.minWidth = "450px";
                btn.innerHTML = `Download ${file.name}`;
                btn.onclick = function () {
                    downloadFile(file.url, file.name, btn);
                }
                root.appendChild(btn);
            });

            let btn = document.createElement("button");
            btn.style.minWidth = "450px";
            btn.innerHTML = `Print ${presentation_data.Title}`;
            btn.onclick = function () {
                let e = {
                    ...presentation_data,
                    "type": 2,
                }
                console.log(e);
                localStorage.setItem("rain_print", JSON.stringify(e));

                go_print(card_data.type, presentation_data.id, card_data.courseware_id);
            }
            root.appendChild(btn);
        } else if (card_data.type == 14) {
            // console.log(card_data);

            let lesson_data = await YuKeTangAPIs.get_lesson_summary(card_data.courseware_id);
            lesson_data.presentations.forEach(presentation => {
                let btn = document.createElement("button");
                btn.style.minWidth = "450px";
                btn.innerHTML = `Print ${presentation.title} (${presentation.id})`;
                btn.onclick = function () {
                    go_print(card_data.type, presentation.id, card_data.courseware_id);
                };
                root.appendChild(btn);
            });
            let btn = document.createElement("button");
            btn.style.minWidth = "450px";
            btn.innerHTML = `Print All`;
            btn.onclick = function () {
                const interval = 1000;
                lesson_data.presentations.forEach((presentation, index) => {
                    setTimeout(function () {
                        go_print(card_data.type, presentation.id, card_data.courseware_id);
                    }, index * interval);
                });
            }
            root.appendChild(btn);
        }
        mount.after(root);
    }

    // Main logic for handling different pages
    if (window.location.pathname === "/web/print") {
        console.log("Handling /web/print");

        const mode_default = 2; // TODO: 设计为用户可编辑模式

        window.onload = function () {
            const print_btn = document.querySelector(".J_print");
            const mode_list = document.querySelector(".J_print_mode");
            const mode_options = mode_list.querySelectorAll("li");

            mode_options.forEach(option => {
                if (option.getAttribute("data-mode") == mode_default) {
                    option.click();
                }
            });

            print_btn.click();
        };
    } else if (window.location.pathname.startsWith("/v2/web/studentLog")) {
        console.log("Handling /v2/web/studentLog");

        let observer = new MutationObserver(function (mutations) {
            for (const mutation of mutations) {
                if (mutation.type === 'childList') {
                    for (const node of mutation.addedNodes) {
                        if (node.classList && node.classList.contains('studentCard')) {
                            setTimeout(() => {
                                student_card_update(node);
                            }, 1000);
                        }
                    }
                }
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }
})();